package com.example.grape_effect.effet.filter

import android.graphics.SurfaceTexture;
import android.util.Log
import com.example.grape_effect.gl.common.OesTexture
import com.example.grape_effect.gl.common.ShaderConstant
import com.example.grape_effect.gl.common.ShaderParameter
import com.example.grape_effect.gl.glHelper.TextureHelper
import com.example.grape_effect.gl.glutils.BufferUtil

class CameraFilter : LYFilter() {
    private val coordCameraFront = BufferUtil.floatToBuffer(
        floatArrayOf(
            1f, 1f,
            0f, 1f,
            1f, 0f,
            0f, 0f

        )
    )
    private val coordCameraBack = BufferUtil.floatToBuffer(
        floatArrayOf(
            0f, 1f,
            1f, 1f,
            0f, 0f,
            1f, 0f
        )
    )
    override var vertexShader = ShaderConstant.NO_FILTER_VERTEX_SHADER
    override var fragmentShader = """#extension GL_OES_EGL_image_external : require
                precision mediump float;
                varying vec2 textureCoordinate;
                uniform samplerExternalOES inputTexture;

                void main()
                {
                    gl_FragColor = texture2D( inputTexture, textureCoordinate );
                }"""

    private lateinit var oesTexture: OesTexture
    var surfaceTexture: SurfaceTexture? = null

    override fun addParameters() {
        parameters["vPosition"] = ShaderParameter(
            "vPosition",
            ShaderParameter.TYPE_ATTRIBUTE,
            ShaderParameter.VALUE_TYPE_ATTRIBUTE_PARAMETER
        )
        parameters["inputTextureCoordinate"] = ShaderParameter(
            "inputTextureCoordinate",
            ShaderParameter.TYPE_ATTRIBUTE,
            ShaderParameter.VALUE_TYPE_ATTRIBUTE_PARAMETER
        )
        parameters["inputTexture"] = ShaderParameter(
            "inputTexture",
            ShaderParameter.TYPE_TEXTURE,
            ShaderParameter.VALUE_TYPE_IMAGE_TEXTURE
        )
    }

    override fun setDefaultParameterValues() {
        oesTexture = OesTexture()
        parameters["vPosition"]?.value =
            ShaderParameter.AttributeParameter(ShaderConstant.POSITIONS, 2)
        parameters["inputTextureCoordinate"]?.value = ShaderParameter.AttributeParameter(
            ShaderConstant.COORDINATE, 2
        )
        parameters["inputTexture"]?.value = oesTexture
    }

    fun initSurfaceTexture() {
        surfaceTexture ?: let {
            val oesTextureArray = IntArray(1)
            TextureHelper.createOESTexture(oesTextureArray)
            surfaceTexture = SurfaceTexture(oesTextureArray[0])
            oesTexture.textureId = oesTextureArray[0]
        }
    }

    // this should use in front open camera
    override fun initProgram() {
        super.initProgram()
        surfaceTexture ?: let {
            val oesTextureArray = IntArray(1)
            TextureHelper.createOESTexture(oesTextureArray)
            surfaceTexture = SurfaceTexture(oesTextureArray[0])
            oesTexture.textureId = oesTextureArray[0]

        }
    }

    fun setCameraId(cameraId: String) {
        when (cameraId) {
            "0" -> {
                parameters["inputTextureCoordinate"]?.value =
                    ShaderParameter.AttributeParameter(coordCameraBack, 2)
            }
            "1" -> {
                parameters["inputTextureCoordinate"]?.value =
                    ShaderParameter.AttributeParameter(coordCameraFront, 2)
            }
            else -> {
                parameters["inputTextureCoordinate"]?.value =
                    ShaderParameter.AttributeParameter(coordCameraBack, 2)
                Log.e("Camera2Filter", "please set the cameraId first !")
            }
        }
    }

    override fun draw() {
        initProgram()
        surfaceTexture?.updateTexImage()
        super.draw()
    }

}